{{!

  Copyright (c) Meta Platforms, Inc. and affiliates.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

}}{{#struct:fields}}
{{#field:use_field_ref?}}

{{^struct:legacy_api?}}
 private:
{{/struct:legacy_api?}}
  {{> common/field_docblock}}
  template <typename..., typename fbthrift_T = {{field:cpp_storage_type}}>
  {{field:cpp_accessor_attribute}} {{field:field_ref_type}}<const fbthrift_T&> {{field:cpp_name}}_ref() const& {
{{> module_types_h/field_interceptor}}
    return {{^field:has_isset?}}{{field:field_ref_type}}<const fbthrift_T&>{{/field:has_isset?}}{this->{{> common/field_value}}{{> module_types_h/field_ref_args}}};
  }

  {{> common/field_docblock}}
  template <typename..., typename fbthrift_T = {{field:cpp_storage_type}}>
  {{field:cpp_accessor_attribute}} {{field:field_ref_type}}<fbthrift_T&> {{field:cpp_name}}_ref() & {
{{> module_types_h/field_interceptor}}
    return {{^field:has_isset?}}{{field:field_ref_type}}<fbthrift_T&>{{/field:has_isset?}}{this->{{> common/field_value}}{{> module_types_h/field_ref_args}}};
  }

  {{> common/field_docblock}}
  template <typename..., typename fbthrift_T = {{field:cpp_storage_type}}>
  {{field:cpp_accessor_attribute}} {{field:field_ref_type}}<fbthrift_T&&> {{field:cpp_name}}_ref() && {
{{> module_types_h/field_interceptor}}
    return {{^field:has_isset?}}{{field:field_ref_type}}<fbthrift_T&&>{{/field:has_isset?}}{static_cast<fbthrift_T&&>(this->{{> common/field_value}}){{> module_types_h/field_ref_args}}};
  }
{{^struct:legacy_api?}}
 public:
{{/struct:legacy_api?}}
{{#field:eligible_for_storage_name_mangling?}}

  {{> common/field_docblock}}
  template <typename..., typename fbthrift_T = {{field:cpp_storage_type}}>
  {{field:cpp_accessor_attribute}} {{field:field_ref_type}}<const fbthrift_T&> {{field:cpp_name}}() const& {
{{> module_types_h/field_interceptor}}
    return {{^field:has_isset?}}{{field:field_ref_type}}<const fbthrift_T&>{{/field:has_isset?}}{this->{{> common/field_value}}{{> module_types_h/field_ref_args}}};
  }

  {{> common/field_docblock}}
  template <typename..., typename fbthrift_T = {{field:cpp_storage_type}}>
  {{field:cpp_accessor_attribute}} {{field:field_ref_type}}<fbthrift_T&> {{field:cpp_name}}() & {
{{> module_types_h/field_interceptor}}
    return {{^field:has_isset?}}{{field:field_ref_type}}<fbthrift_T&>{{/field:has_isset?}}{this->{{> common/field_value}}{{> module_types_h/field_ref_args}}};
  }

  {{> common/field_docblock}}
  template <typename..., typename fbthrift_T = {{field:cpp_storage_type}}>
  {{field:cpp_accessor_attribute}} {{field:field_ref_type}}<fbthrift_T&&> {{field:cpp_name}}() && {
{{> module_types_h/field_interceptor}}
    return {{^field:has_isset?}}{{field:field_ref_type}}<fbthrift_T&&>{{/field:has_isset?}}{static_cast<fbthrift_T&&>(this->{{> common/field_value}}){{> module_types_h/field_ref_args}}};
  }
{{/field:eligible_for_storage_name_mangling?}}
{{/field:use_field_ref?}}
{{^field:use_field_ref?}}
{{^struct:legacy_api?}}
 private:
{{/struct:legacy_api?}}
  {{> common/field_docblock}}
  template <typename..., typename fbthrift_T = {{field:cpp_storage_type}}>
  {{field:cpp_accessor_attribute}} fbthrift_T& {{field:cpp_name}}_ref() & {
{{> module_types_h/field_interceptor}}
    return {{> common/field_value}};
  }

  {{> common/field_docblock}}
  template <typename..., typename fbthrift_T = {{field:cpp_storage_type}}>
  {{field:cpp_accessor_attribute}} const fbthrift_T& {{field:cpp_name}}_ref() const& {
{{> module_types_h/field_interceptor}}
    return {{> common/field_value}};
  }

  {{> common/field_docblock}}
  template <typename..., typename fbthrift_T = {{field:cpp_storage_type}}>
  {{field:cpp_accessor_attribute}} fbthrift_T&& {{field:cpp_name}}_ref() && {
{{> module_types_h/field_interceptor}}
    return static_cast<fbthrift_T&&>({{> common/field_value}});
  }

  {{> common/field_docblock}}
  template <typename..., typename fbthrift_T = {{field:cpp_storage_type}}>
  {{field:cpp_accessor_attribute}} const fbthrift_T&& {{field:cpp_name}}_ref() const&& {
{{> module_types_h/field_interceptor}}
    return static_cast<const fbthrift_T&&>({{> common/field_value}});
  }
{{^struct:legacy_api?}}
 public:
{{/struct:legacy_api?}}
{{#field:eligible_for_storage_name_mangling?}}

  {{> common/field_docblock}}
  template <typename..., typename fbthrift_T = {{field:cpp_storage_type}}>
  FOLLY_ERASE fbthrift_T& {{field:cpp_name}}() & {
{{> module_types_h/field_interceptor}}
    return {{> common/field_value}};
  }

  {{> common/field_docblock}}
  template <typename..., typename fbthrift_T = {{field:cpp_storage_type}}>
  FOLLY_ERASE const fbthrift_T& {{field:cpp_name}}() const& {
{{> module_types_h/field_interceptor}}
    return {{> common/field_value}};
  }

  {{> common/field_docblock}}
  template <typename..., typename fbthrift_T = {{field:cpp_storage_type}}>
  FOLLY_ERASE fbthrift_T&& {{field:cpp_name}}() && {
{{> module_types_h/field_interceptor}}
    return static_cast<fbthrift_T&&>({{> common/field_value}});
  }

  {{> common/field_docblock}}
  template <typename..., typename fbthrift_T = {{field:cpp_storage_type}}>
  FOLLY_ERASE const fbthrift_T&& {{field:cpp_name}}() const&& {
{{> module_types_h/field_interceptor}}
    return static_cast<const fbthrift_T&&>({{> common/field_value}});
  }
{{/field:eligible_for_storage_name_mangling?}}
{{/field:use_field_ref?}}
{{/struct:fields}}
{{#struct:mixin_fields}}
{{^struct:legacy_api?}}
 public:
{{/struct:legacy_api?}}
  FOLLY_ERASE auto {{mixin:field_name}}() &           { return {{mixin:name}}_ref()->{{mixin:accessor}}(); }
  FOLLY_ERASE auto {{mixin:field_name}}() const&      { return {{mixin:name}}_ref()->{{mixin:accessor}}(); }
  FOLLY_ERASE auto {{mixin:field_name}}() &&          { return std::move(*{{mixin:name}}_ref()).{{mixin:accessor}}(); }
  FOLLY_ERASE auto {{mixin:field_name}}() const&&     { return std::move(*{{mixin:name}}_ref()).{{mixin:accessor}}(); }
{{^struct:legacy_api?}}
 private:
{{/struct:legacy_api?}}
  [[deprecated("{{mixin:field_name}}_ref() is deprecated, use {{mixin:field_name}}() instead.")]]
  FOLLY_ERASE auto {{mixin:field_name}}_ref() &       { return {{mixin:field_name}}(); }
  [[deprecated("{{mixin:field_name}}_ref() is deprecated, use {{mixin:field_name}}() instead.")]]
  FOLLY_ERASE auto {{mixin:field_name}}_ref() const&  { return {{mixin:field_name}}(); }
  [[deprecated("{{mixin:field_name}}_ref() is deprecated, use {{mixin:field_name}}() instead.")]]
  FOLLY_ERASE auto {{mixin:field_name}}_ref() &&      { return std::move(*this).{{mixin:field_name}}(); }
  [[deprecated("{{mixin:field_name}}_ref() is deprecated, use {{mixin:field_name}}() instead.")]]
  FOLLY_ERASE auto {{mixin:field_name}}_ref() const&& { return std::move(*this).{{mixin:field_name}}(); }
{{/struct:mixin_fields}}
